using Engine;
using Game;
using GameEntitySystem;
using TemplatesDatabase;

namespace SCIENEW {
    public class ComponentRifling : ComponentInventoryBase, ICrafterComponent, IUpdateable {
        public int RemainsSlotIndex => throw new NotImplementedException();
        public int ResultSlotIndex => SlotsCount - 1;
        public static int RequiredHeatLevel => -3;

        CraftingRecipe? m_craftingRecipe;

        public float m_craftingProgress;

        protected bool m_updateCraftingRecipe;

        protected float m_speed = 0.1f;

        public float CraftingProgress => m_craftingProgress;

        public UpdateOrder UpdateOrder => UpdateOrder.Default;

        public ComponentBlockEntity m_componentBlockEntity;

        public SubsystemEnginePower m_subsystemEnginePower;

        public SubsystemTerrain m_subsystemTerrain;


        public override int GetSlotCapacity(int slotIndex, int value) => slotIndex == 0 ? base.GetSlotCapacity(slotIndex, value) : 0;

        public override void AddSlotItems(int slotIndex, int value, int count) {
            m_updateCraftingRecipe = true;
            base.AddSlotItems(slotIndex, value, count);
        }

        public override int RemoveSlotItems(int slotIndex, int count) {
            m_updateCraftingRecipe = true;
            return base.RemoveSlotItems(slotIndex, count);
        }

        public void Update(float dt) {
            if (m_subsystemEnginePower.IsPowered(m_componentBlockEntity.Coordinates, out IEngineComponent engine)) {
                if (m_updateCraftingRecipe) {
                    m_updateCraftingRecipe = false;
                    FindRecipe();
                }
                if (m_craftingRecipe == null) {
                    m_craftingProgress = 0f;
                }
                else {//进度增加，最后合成物品
                    m_craftingProgress = MathUtils.Min(m_craftingProgress + m_speed * dt, 1f);
                    if (m_craftingProgress >= 1f) {
                        if (m_slots[0].Count > 0) m_slots[0].Count--;
                        m_slots[ResultSlotIndex].Value = m_craftingRecipe.ResultValue;
                        m_slots[ResultSlotIndex].Count += m_craftingRecipe.ResultCount;
                        m_craftingRecipe = null;
                        m_craftingProgress = 0f;
                        m_updateCraftingRecipe = true;
                    }
                }
            }
            else {
                m_craftingProgress = 0f;
                m_craftingRecipe = null;
                m_updateCraftingRecipe = true;
            }
        }

        public void FindRecipe() {
            m_craftingRecipe = null;

            //先匹配配方
            ComponentPlayer componentPlayer = FindInteractingPlayer();
            float playerLevel = componentPlayer?.PlayerData.Level ?? 1;
            string[] ingredients = [IECraftingRecipesManager.BlockToIngredient(GetSlotValue(0))];
            m_craftingRecipe = MatchRecipe(m_subsystemTerrain, ingredients, RequiredHeatLevel, playerLevel);

            if (m_craftingRecipe == null) return;

            //再检查配方
            Slot slot = m_slots[ResultSlotIndex];
            int num3 = Terrain.ExtractContents(m_craftingRecipe.ResultValue);
            if (slot.Count != 0
                && (m_craftingRecipe.ResultValue != slot.Value || m_craftingRecipe.ResultCount + slot.Count > BlocksManager.Blocks[num3].GetMaxStacking(m_craftingRecipe.ResultValue))) {
                m_craftingRecipe = null;
            }
        }

        public CraftingRecipe MatchRecipe(SubsystemTerrain terrain, string[] ingredients, float heatLevel, float playerLevel) {
            foreach (var recipe in CraftingRecipesManager.Recipes) {
                if(recipe == null) continue;
                bool matchHeat = heatLevel == recipe.RequiredHeatLevel;
                bool matchPlayerLevel = playerLevel >= recipe.RequiredPlayerLevel;
                bool matchIng = IECraftingRecipesManager.CompareIngredients(recipe.Ingredients[0],ingredients[0]);
                if (matchHeat
                    && matchPlayerLevel
                    && matchIng)
                    return recipe;
            }
            return null;
        }

        public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap) {
            base.Load(valuesDictionary, idToEntityMap);
            m_componentBlockEntity = Entity.FindComponent<ComponentBlockEntity>(true);
            m_subsystemEnginePower = Project.FindSubsystem<SubsystemEnginePower>(true);
            m_subsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
            m_craftingProgress = valuesDictionary.GetValue("CraftingProgress", 0f);
            m_updateCraftingRecipe = true;
        }

        public override void Save(ValuesDictionary valuesDictionary, EntityToIdMap entityToIdMap) {
            base.Save(valuesDictionary, entityToIdMap);
            valuesDictionary.SetValue("CraftingProgress", m_craftingProgress);
        }
    }
}